package com.cognitran.cssvalidator.ant.types;

import java.util.Locale;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.DataType;

import com.cognitran.cssvalidator.ant.output.formatters.OutputFormatter;
import com.cognitran.cssvalidator.ant.output.formatters.SimpleTextFormatter;
import com.cognitran.cssvalidator.ant.output.formatters.W3CStyledTextFormatter;
import com.cognitran.cssvalidator.ant.output.formatters.XMLOutputFormatter;


/**
 * An ant data type to wrapper output formats
 * 
 * @author garethf
 */
public class Format extends DataType
{

    /** A locale used for uppercase conversion - en_US is safe, as no non-ASCII characters are expected. */
    private static final Locale US_LOCALE = new Locale("en", "US");
    
    
    /** The type attribute of the format to use. */
    private String type;

    
    /**
     * Get the output format requested.
     * 
     * @return The string type of the requested format.
     */
    public String getType()
    {
        return type;
    }

    
    /**
     * Set the requested output format.
     * 
     * @param type The string type of the requested format.
     */
    public void setType(final String type)
    {
    	if (type == null || Type.valueOf(type.toUpperCase(US_LOCALE)) == null)
    	{
    		throw new BuildException("Unknown formatting type: " + type);
    	}
    	
        this.type = type;
    }
    
    
    /**
     * Get the <code>FormatType</code> that this format represents.
     * 
     * @return The <code>FormatType</code> that represents the requested output format.
     */
    public Type getFormatType()
    {
    	Type formatType = Type.valueOf(type.toUpperCase(US_LOCALE));
        return formatType;
    }
    

    /**
     * Get the output formatter for this output format type.
     * 
     * @return An instance of an <code>OutputFormatter</code> that can format output.
     */
	public OutputFormatter getFormatter() 
	{
		try 
		{
			return getFormatType().getFormatterClass().newInstance();
		}
		catch (InstantiationException e) 
		{
			throw new BuildException("Unable to creaet output formatter instance.", e);
		}
		catch (IllegalAccessException e) 
		{
			throw new BuildException("Unable to creaet output formatter instance.", e);
		}
	}
    
    
    /**
     * The types of output formatting that are allowed.
     *  
     * @author garethf
     */
    public static enum Type
    {
    	
    	/** Simple, formatted text output. */
    	TEXT(SimpleTextFormatter.class),

    	/** W3C style formatted text output. */
    	W3C_TEXT(W3CStyledTextFormatter.class),

    	/** XML output. */
    	XML(XMLOutputFormatter.class);

    	
    	/** The formatter class to use for this type. */
    	private Class<? extends OutputFormatter> formatterClass;
    	
    	
    	/**
    	 * Create an output format type.
    	 * 
    	 * @param formatterClass The formatter class that will be used.
    	 */
    	Type(final Class<? extends OutputFormatter> formatterClass)
    	{
    		this.formatterClass = formatterClass;
    	}
    	
    	/**
    	 * Get the formatter class that can be used to generated output for this type.
    	 * 
    	 * @return The class that can be used as a formatter for this output type.
    	 */
		public Class<? extends OutputFormatter> getFormatterClass() 
		{
			return formatterClass;
		}
    }

}
